package utils;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.util.LinkedHashMap;
import java.util.Map;

import play.Logger;
import play.cache.Cache;

/**
 * 字典工具
 * 
 * @author ultrafrog
 * @version 1.0, 2015-04-26
 * @since 1.0
 */
public abstract class Dicts {

	private static final String CACHE_PREFIX	= "dbcenter_cache_dict_";
	
	/**
	 * 元素映射
	 * 
	 * @param type
	 * @return
	 */
	public static Map<Object, String> elements(Class<?> type) {
		// 从缓存中读取数据
		Map<Object, String> mElem = (Map<Object, String>) Cache.get(CACHE_PREFIX + type.getName());
		
		// 判断数据是否已经缓存
		// 若尚未缓存则加载数据并进行缓存
		if (mElem == null) {
			// 初始化
			Logger.info("caching dict '%s' start...", type.getName());
			mElem = new LinkedHashMap<Object, String>();
			Field[] fields = type.getDeclaredFields();
			
			// 遍历所有字段并进行处理
			for (Field field: fields) {
				Element element = field.getAnnotation(Element.class);
				if (element != null) {
					try {
						Object key = field.get(type);
						String val = element.value();
						mElem.put(key, val);
						Logger.info("cache dict '%s' field '%s: %s'", type.getName(), key, val);
					} catch (IllegalArgumentException | IllegalAccessException e) {
						Logger.error(e, e.getMessage());
					}
				}
			}
			
			// 缓存数据
			Cache.add(CACHE_PREFIX + type.getName(), mElem);
			Logger.info("cache dict '%s' completed.", type.getName());
		}
		
		// 返回结果
		return mElem;
	}
	
	/**
	 * 元素映射
	 * 
	 * @param type
	 * @param excludes
	 * @return
	 */
	public static Map<Object, String> elements(Class<?> type, Object... excludes) {
		Map<Object, String> copy = new LinkedHashMap<Object, String>(elements(type));
		for (Object e: excludes) copy.remove(e);
		return copy;
	}
	
	/**
	 * 元素名称
	 * 
	 * @param key
	 * @param type
	 * @return
	 */
	public static String name(Object key, Class<?> type) {
		return elements(type).get(key);
	}
	
	/**
	 * 读取字典元素名称
	 * 
	 * @param key
	 * @param defaultValue
	 * @param type
	 * @return
	 */
	public static String name(Object key, String defaultValue, Class<?> type) {
		return Strings.empty(name(key, type), defaultValue);
	}
	
	/**
	 * 布尔值
	 * 
	 * @author ultrafrog
	 * @version 1.0, 2015-04-26
	 * @since 1.0
	 */
	public static final class Bool {
		
		@Element("是")
		public static final String TRUE		= "01";
		
		@Element("否")
		public static final String FALSE	= "00";
	}
	
	/**
	 * 元素注解
	 * 
	 * @author ultrafrog
	 * @version 1.0, 2015-04-26
	 * @since 1.0
	 */
	@Target(ElementType.FIELD)
	@Retention(RetentionPolicy.RUNTIME)
	@Documented
	public @interface Element {
		public String value() default "";
	}
}
